﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CharmL.Helper;

namespace CharmL {
    public class IncrCmpComparer : Comparer<Eqnode> {

        public override int Compare(Eqnode n1, Eqnode n2) {
            if (n1 != null && n2 != null) {
                if (n1.Sup < n2.Sup) return 1; else if (n1.Sup == n2.Sup) { return 0; }
            }
            return -1;

            //if (Eqnode.IncrCmp(x, y)) return 1;
            //return -1;
        }
    }

    public class DecrCmpComparer : Comparer<Eqnode> {

        public override int Compare(Eqnode x, Eqnode y) {
            if (Eqnode.DecrCmp(x, y)) return 1;
            return -1;
        }
    }

    public class Eqnode {
        public int Val; //the item
        public int Sup; //support
        public List<int> TidSet; //tidlist for this item

        public int MaxSup; //number of maximal itemsets
        public List<int> MaxSet; //the maximal itemsets containing this itemset
        public int Hval; //hash value for closed itemsets
        public Paramenters Param;

        public Eqnode(int v, int s = 0, int m = 0) {
            Val = v;
            Sup = s;
            MaxSup = m;
            Hval = 0;
            TidSet = new List<int>();
            MaxSet = new List<int>();
        }

        public static bool IncrCmp(Eqnode n1, Eqnode n2) {
            if (n1 != null && n2 != null && n1.Sup < n2.Sup) return true;
            return false;
            //static bool incr_cmp (Eqnode *n1, Eqnode *n2){
            //      //cout << "CAM<E HEREEE INCR\n";
            //      if ((n1)->sup < (n2)->sup) return true;
            //      else return false;
            //   }
        }
        public static bool DecrCmp(Eqnode n1, Eqnode n2) {
            if (n1.Sup < n2.Sup) return false;
            return true;
            //static bool decr_cmp (Eqnode *n1, Eqnode *n2){
            //      //cout << "CAM<E HEREEE DECR\n";
            //      if ((n1)->sup < (n2)->sup) return false;
            //      else return true;
            //   } 
        }


        //class Eqnode{
        //public:
        //   int val; //the item
        //   int sup; //support
        //   idlist tidset; //tidlist for this item

        //   int maxsup; //number of maximal itemsets
        //   idlist maxset; //the maximal itemsets containing this itemset
        //   int hval; //hash value for closed itemsets


        //   Eqnode(int v, int s=0, int m=0): val(v), sup(s), maxsup(m), hval(0){
        //      //cmaxset(1);
        //   }
        //   int &support(){ return sup; }
        //   int &maxsupport(){ return maxsup; }
        //   int &hashval(){ return hval; }
        //   static bool incr_cmp (Eqnode *n1, Eqnode *n2){
        //      //cout << "CAM<E HEREEE INCR\n";
        //      if ((n1)->sup < (n2)->sup) return true;
        //      else return false;
        //   }
        //   static bool decr_cmp (Eqnode *n1, Eqnode *n2){
        //      //cout << "CAM<E HEREEE DECR\n";
        //      if ((n1)->sup < (n2)->sup) return false;
        //      else return true;
        //   }
        //   ostream & print_node(ostream& fout, bool printval=true);
        //   friend ostream & operator<<(ostream& ostr, Eqnode& eqn);
        //};

        public override string ToString() {
            //TODO
            StringBuilder builder = new StringBuilder(string.Empty);
            List<int> fidx = new List<int>();//Dbase_Ctrl_Blk.FreqIdx;
            builder.AppendFormat("{0} - {1} {2}", fidx[Val], Sup, Hval);
            if (Paramenters.output_idlist) {
                builder.AppendFormat(" [{0}]", TidSet.ToString());
                if (Paramenters.alg_type == alg_vals.basicmax || Paramenters.alg_type == alg_vals.maxcharm || Paramenters.closed_type == closed_vals.cmax) {
                    builder.AppendFormat(" -- {0} [ {1} ]", MaxSup, MaxSet.ToString());
                }
            }
            return builder.ToString();
            //        ostream & operator<<(ostream& ostr, Eqnode& eqn){
            //   int *fidx = Dbase_Ctrl_Blk::FreqIdx;
            //   ostr << fidx[eqn.val] << " - " << eqn.support(); // << " " << eqn.hashval();
            //   if (output_idlist){
            //      ostr << " [" << eqn.tidset << "]";
            ////       if (alg_type == basicmax || alg_type == maxcharm || closed_type == cmax) 
            ////          ostr << " -- " << eqn.maxsup << " {" << eqn.maxset << "}";
            //   }
            //   return ostr;
            //}
        }


        public void PrintNode(StreamWriter writer, bool printVal) {
            if (printVal) {
                //TODO
                List<int> fidx = new List<int>();// Dbase_Ctrl_Blk.FreqIdx;
                writer.Write(fidx[Val] + " - " + Sup);
            }

            if (Paramenters.output_idlist) {
                writer.Write(" [" + TidSet.ToString() + "]");
            }
            //ostream & Eqnode::print_node(ostream& ostr, bool printval)
            //{
            //   if (printval){
            //      int *fidx = Dbase_Ctrl_Blk::FreqIdx;
            //      ostr << fidx[val] << " - " << sup;
            //   }

            //   if (output_idlist){
            //      ostr << " [" << tidset << "]";
            //   }
            //   return ostr;

            //}
        }
    }
}